using System;
using System.Data;
using System.Configuration;
using System.Collections.Generic;
using System.Collections;
using Pheonix.Fashionzoomer.Entity.SqlServer2000;
using Pheonix.CodeLibrary.Mail;
using Pheonix.CodeLibrary.Web;
using System.Web.Configuration;
using Pheonix.Fashionzoomer.DAL;
using System.Text;
using System.Web;
using Pheonix.CodeLibrary;

/// <summary>
/// Summary description for UserManager
/// </summary>

namespace Pheonix.Fashionzoomer.BLL
{
    public enum CommonRoles
    {
        BasicUser = 4,
        ShopOwner = 3,
        Operator = 2,
        Admin = 1
    }

    public sealed class UserManager
    {
        public static string EncryptPassword(string plainPassword)
        {
            SiteConfigSection config = SiteConfigSection.SiteConfiguration;
            string encryptedPassword = Utility.Encrypt(plainPassword, config.SecurityKey, true);
            return encryptedPassword;
        }

        public static string DecryptPassword(string encryptedPassword)
        {
            SiteConfigSection config = SiteConfigSection.SiteConfiguration;
            string plainPassword = Utility.Decrypt(encryptedPassword, config.SecurityKey, true);
            return plainPassword;
        }

        private UserManager() { }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="userEmail"></param>
        /// <param name="userPassword"></param>
        /// <param name="membershipId"></param>
        /// <returns></returns>
        public static CurrentUser RegisterNewUser(string userName, string userEmail, string userPassword, 
                                                    int membershipId)
        {
            SiteConfigSection config = SiteConfigSection.SiteConfiguration;

            //user email and password is used to make the encryption
            string confirmationCode = Guid.NewGuid().ToString().Replace("-","").Replace(" ","");
            
            string encryptedPassword = Pheonix.CodeLibrary.Utility.Encrypt(userPassword, config.SecurityKey, true);           

            //user is activated from registration time ,but if the user does not verified his/her account 
            //then account will be deleted.
            bool isActive = true;
            bool isVerified = false;
            DateTime lastVisit = System.DateTime.Now;
            string fullName = "New User";

            int newUserId = User.CreateNewUser(userName, userEmail, encryptedPassword, isActive, isVerified,
                                                confirmationCode, lastVisit, membershipId);
            int profileId = Profile.CreateNewProfile("New", "User", 0, 0, config.DefaultTheme, newUserId);

            CurrentUser currentUser = new CurrentUser(newUserId, userName, userEmail, fullName, lastVisit, membershipId);

            System.Collections.Specialized.NameValueCollection nvc = new System.Collections.Specialized.NameValueCollection();

            StringBuilder confirmationUrl = new StringBuilder();
            confirmationUrl.Append("http://");
            confirmationUrl.Append(config.CurrentDomain);
            confirmationUrl.Append("/public/activation.aspx?");
            confirmationUrl.Append("confirmationCode=");
            confirmationUrl.Append(HttpUtility.UrlEncode(confirmationCode));

            nvc.Add("ReceiverName", fullName);
            nvc.Add("ReceiverEmail", userEmail);
            nvc.Add("Subject", "FashionZoomer - Registration Information");
            nvc.Add("<UserName>", userName);
            nvc.Add("<Password>", userPassword);
            nvc.Add("<ConfirmationUrl>", confirmationUrl.ToString());

            try
            {
                MailSender.SendTemplatedMaill(SiteConfigSection.MailConfigurations, "/mailtemplates/RegisteredUser.txt", nvc);
            }
            catch (Exception ex)
            {
                Exception customEx = new Exception("Class:UserManger,Method:RegisterNewUser", ex.InnerException);
                throw customEx;
            }

            return currentUser;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <param name="cause"></param>
        /// <returns></returns>
        public static bool CancelRegistration(int userId, string cause)
        {
            CurrentUser currentUser = CustomCommand.GetBasicUserInfo(userId);

            if (User.DeleteUser(userId))
            {
                System.Collections.Specialized.NameValueCollection nvc = new System.Collections.Specialized.NameValueCollection();
                nvc.Add("Subject", "Sorry, Your registration has been canceled.");
                nvc.Add("ReceiverName", currentUser.FullName);
                nvc.Add("ReceiverEmail", currentUser.UserEmail);
                nvc.Add("<UserFullName>", currentUser.FullName);
                nvc.Add("<Cause>", cause);

                try
                {
                    MailSender.SendTemplatedMaill(SiteConfigSection.MailConfigurations, "/mailtemplates/CancelRegistration.txt", nvc);
                    return true;
                }
                catch (Exception ex)
                {
                    Exception customEx = new Exception("Class:UserManger,Method:CancelRegistration", ex.InnerException);
                    throw customEx;
                }
            }

            return false;
        }

        /// <summary>
        /// This method does the login operation. Takes username and password
        /// and logges in the user by authenticating the information from
        /// tbl_user in the database.
        /// </summary>
        /// <param name="userName">username of the user to be logged in</param>
        /// <param name="userPassword">password of the user to be logged in</param>
        /// <returns>Instance of CurrentUser object as basic information of logged in user</returns>
        public static CurrentUser LogonUser(string userName, string userPassword)
        {
            // Getting the site configuration object to read custom web.config values
            SiteConfigSection config = SiteConfigSection.SiteConfiguration;

            // Convert user password to encrypted form to match the database encrypted password for the user
            userPassword = Pheonix.CodeLibrary.Utility.Encrypt(userPassword, config.SecurityKey, true); 
          
            // Fetch user record that matches the provided username and password
            DataRow dataRow = CustomCommand.GetUserByUsernameAndPassword(userName, userPassword);

            // Initializing A CurrentUser instance
            CurrentUser currentUser = null;

            // If data was found
            if (dataRow != null)
            {
                // Whether the user account is currently active
                bool isUserActive = (bool)dataRow["is_active"];
                bool isVerfied = (bool)dataRow["is_verified"];
                // If the user account is currently active
                if (isUserActive && isVerfied)
                {
                    // Construct a CurrentUser instance with the fetched data
                    currentUser = new CurrentUser((int)dataRow["id"],
                                                  dataRow["user_name"].ToString(),
                                                  dataRow["user_email"].ToString(),
                                                  dataRow["user_full_name"].ToString(),
                                                  (DateTime)dataRow["last_visit"],
                                                  (int)dataRow["membership_id"]);
                }
            }
            // return the current user, if data was not found, null gets returned as default value of CurrentUser
            return currentUser;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <param name="userEmail"></param>
        /// <param name="userPassword"></param>
        /// <param name="isActive"></param>
        /// <param name="isVerified"></param>
        /// <param name="confirmationCode"></param>
        /// <param name="lastVisit"></param>
        /// <param name="membershipId"></param>
        /// <returns></returns>
        //public static bool ChangeMembership(int id, string userEmail, string userPassword, bool
        //                                    isActive, bool isVerified, string confirmationCode,
        //                                    DateTime lastVisit, int membershipId)
        //{
        //    return User.UpdateUser(id, userEmail, userPassword, isActive, isVerified, confirmationCode, lastVisit, membershipId);
        //}

        /// <summary>
        /// Account registration verification is done by this method.
        /// </summary>
        /// <param name="userName">Username used for registration</param>
        /// <param name="confirmationCode">Confirmation code sent to email</param>
        /// <param name="currentUser">CurrentUser instance</param>
        /// <returns>return true if the registration successfuly verified, and also an instance of CurrentUser</returns>
        public static bool VerifyAccount(string confirmationCode, out CurrentUser currentUser)
        {
            try
            {
                SiteConfigSection config = SiteConfigSection.SiteConfiguration;
                
                currentUser = new CurrentUser();

                if (CustomCommand.VerifyConfirmation(confirmationCode, out currentUser))
                {
                    System.Collections.Specialized.NameValueCollection nvc = new System.Collections.Specialized.NameValueCollection();
                    nvc.Add("ReceiverName", currentUser.FullName);
                    nvc.Add("ReceiverEmail", currentUser.UserEmail);
                    nvc.Add("Subject", "FashionZoomer - Account Verified");
                    nvc.Add("<UserName>", currentUser.UserName);

                    try
                    {
                        MailSender.SendTemplatedMaill(SiteConfigSection.MailConfigurations, "/mailtemplates/AccountVerification.txt", nvc);
                    }
                    catch (Exception ex)
                    {
                        Exception customEx = new Exception("Class:UserManger,Method:ActivateAccount", ex);
                        throw customEx;
                    }
                    return true;
                }
                else
                    return false;
            }
            catch (Exception ex)
            {
                Exception customEx = new Exception("Class:UserManger,Method:ActivateAccount", ex);
                throw customEx;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        //public static bool BlockUser(int id, string cause)
        //{
        //    User user = User.GetUserById(id);
        //    user.IsActive = false;
        //    bool isUserBlocked = User.UpdateUser(user);

        //    System.Collections.Specialized.NameValueCollection nvc = new System.Collections.Specialized.NameValueCollection();
        //    nvc.Add("<username>", user.UserEmail);
        //    nvc.Add("<cause>", cause);

        //    try
        //    {
        //        MailSender.SendTemplatedMaill(UserManager.GetMailSettings(), "/mailtemplates/BlockUser.txt", nvc);
        //    }
        //    catch (Exception ex)
        //    {
        //        Exception customEx = new Exception("Class:UserManger,Method:BlockUser", ex.InnerException);
        //    }

        //    return isUserBlocked;
        //}

        /// <summary>
        /// /
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        //public static bool UnblockUser(int id)
        //{
        //    User user = User.GetUserById(id);
        //    user.IsActive = true;
        //    bool isUserUnblock = User.UpdateUser(user);

        //    System.Collections.Specialized.NameValueCollection nvc = new System.Collections.Specialized.NameValueCollection();
        //    nvc.Add("<username>", user.UserEmail);

        //    try
        //    {
        //        MailSender.SendTemplatedMaill(UserManager.GetMailSettings(), "/mailtemplates/UnblockUser.txt", nvc);
        //    }
        //    catch (Exception ex)
        //    {
        //        Exception customEx = new Exception("Class:UserManger,Method:UnblockUser", ex.InnerException);
        //        throw customEx;
        //    }

        //    return isUserUnblock;
        //}

        /// <summary>
        /// /
        /// </summary>
        /// <returns></returns>
        public static bool UserLogoff()
        {
            throw new NotImplementedException();
        }

        public static bool IsUserNameAvailable(string userName)
        {
            return !CustomCommand.IsUserNameAlreadyRegistered(userName);
        }

        /// <summary>
        /// The change password method does not changed the password directly..
        /// this method will generate a conformation code with new password and stored it 
        /// into db as conformation code send a email to user with that code.
        /// when a user click that lin form mail and if confirmation code is changed only
        /// then password will changed by ConfirmChangePassword method.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="userOldPassword"></param>
        /// <param name="userNewPassword"></param>
        /// <returns></returns>
        //public static bool ChangePassword(int id, string userOldPassword, string userNewPassword)
        //{
        //    User user = User.GetUserById(id);
        //    string _confirmationCode = Pheonix.CodeLibrary.Utility.Encrypt(userNewPassword, UserManager.GetSecurityKey(), true);
        //    user.ConfirmationCode = _confirmationCode;
        //    bool isConfirmationCodeUpdated = User.UpdateUser(user);

        //    System.Collections.Specialized.NameValueCollection nvc = new System.Collections.Specialized.NameValueCollection();
        //    nvc.Add("<username>", user.UserEmail);
        //    nvc.Add("<id>", user.Id.ToString());
        //    nvc.Add("<confirmationCode>", user.ConfirmationCode);

        //    try
        //    {
        //        MailSender.SendTemplatedMaill(UserManager.GetMailSettings(), "/mailtemplates/ChangePassword.txt", nvc);
        //    }
        //    catch (Exception ex)
        //    {
        //        Exception customEx = new Exception("Class:UserManger,Method:ChangePassword", ex.InnerException);
        //        throw customEx;
        //    }

        //    return isConfirmationCodeUpdated;

        //}

        /// <summary>
        /// /
        /// </summary>
        /// <param name="Id"></param>
        /// <param name="confirmationCode"></param>
        /// <returns></returns>
        //public static bool ConfirmChangePassword(int Id, string confirmationCode)
        //{
        //    User user = User.GetUserById(Id);

        //    string userNewPassword = Pheonix.CodeLibrary.Utility.Decrypt(confirmationCode, UserManager.GetSecurityKey(), true);
        //    string userOldPassword = user.UserPassword;

        //    if (DAL.CustomCommand.PasswordChanged(user.UserEmail, userOldPassword, userNewPassword))
        //    {
        //        return true;
        //    }
        //    else
        //    {
        //        return false;
        //    }
        //}

        public static void GetUserAccountInfo(int userId, out User user, out Profile profile)
        {
            user = User.GetUserById(userId);
            Pheonix.CodeLibrary.Data.CustomCollection<Profile> profiles = Profile.GetProfileByUserId(userId);
            if (profiles.Count > 0)
                profile = (Profile)profiles[0];
            else
                profile = new Profile();
        }

        public static bool SetNewPassword(int userId, string userNewPassword)
        {
            Pheonix.Fashionzoomer.Entity.SqlServer2000.User user = Pheonix.Fashionzoomer.Entity.SqlServer2000.User.GetUserById(userId);
            if (user != null)
            {
                user.UserPassword = userNewPassword;
                return user.Save();
            }
            else
                return false;
        }

        public static bool UpdateUserProfile(int userId, string userFirstName, string userLastName, 
            string userEmail, string userTimeZone, string userTheme)
        {
            Pheonix.CodeLibrary.Data.CustomCollection<Profile> profiles = Profile.GetProfileByUserId(userId);
            Profile profile = null;
            if (profiles.Count > 0)
                profile = (Profile)profiles[0];
            else
                profile = new Profile();

            if (profile != null)
            {
                profile.UserFirstName = userFirstName;
                profile.UserLastName = userLastName;
                profile.SelectedTheme = userTheme;
                profile.TimeZone = int.Parse(userTimeZone);

                User user = User.GetUserById(userId);
                if (user != null)
                {
                    user.UserEmail = userEmail;
                }

                return (user.Save() && profile.Save());
            }
            else
                return false;
        }
    }
}
